// ****************************************************************************
// *     Filename:  g4test.cc
// *      Created:  2012-09-14 11:07:01
// *      Version:  1.0
// *     Revision:  0
// *       Author:  Tran Hoai Nam (nam), nam@kuno-g.phys.sci.osaka-u.ac.jp
// * Organization:  Osaka University
// *      License:  Geant4 Software License
// *                http://geant4.cern.ch/license/LICENSE.html
// *  Description:  Main
// ****************************************************************************


#include "G4RunManager.hh"
#include "G4UImanager.hh"
#include "G4PhysListFactory.hh"
#include "G4VModularPhysicsList.hh"
#include "Randomize.hh"

#include "PhysicsList.hh"
#include "PhysicsListMessenger.hh"
#include "DetectorConstruction.hh"
#include "PrimaryGeneratorAction.hh"
#include "EventAction.hh"
#include "HistoManager.hh"
//#include "TrackingAction.hh"
//#include "RunAction.hh"

#ifdef G4VIS_USE
#include "G4VisExecutive.hh"
#endif

#ifdef G4UI_USE
#include "G4UIExecutive.hh"
#endif
int main(int argc,char** argv)
{
	//Random engine
	long seeds[1];	//default Random engine: HepJamesRandom that needs only 1 seed
	time_t systime = time(NULL);
	seeds[0] = (long) systime;
	G4cout<<systime<<"\t"<<seeds[0]<<G4endl;
	CLHEP::HepRandom::setTheSeeds(seeds);
	CLHEP::HepRandom::showEngineStatus();

	// Construct the default run manager
	G4RunManager* runManager = new G4RunManager;
	// Save random seed in order to re-run later
	//runManager->SetRandomNumberStore(true);

	// set mandatory initialization classes
	//G4VUserDetectorConstruction* detector = new DetectorConstruction;
	DetectorConstruction* detector = new DetectorConstruction;
	runManager->SetUserInitialization(detector);

	//Physics list, using physics builder
	G4PhysListFactory physListFact;
	G4VModularPhysicsList* modulPhysList = 0;
	PhysicsListMessenger* physListMess = 0;
	G4String physName = "";

	// Physics List name defined via 2nd argument
	//if (argc==3) { physName = argv[2]; }

	// Physics List name defined via environment variable
	//char* path = getenv("PHYSLIST");
	//if (path) { physName = G4String(path); }

	physName = "LHEP_EMV";

	// reference PhysicsList via its name
	if(physListFact.IsReferencePhysList(physName))
	{
		modulPhysList = physListFact.GetReferencePhysList(physName);
		physListMess = new PhysicsListMessenger();
	}

	// local Physics List (default)
	if(!modulPhysList)
	{
		modulPhysList = new PhysicsList();
	}

	// define physics
	runManager->SetUserInitialization(modulPhysList);


	//HistoManager - will be used in EventAction
	G4String output;
	//  File name is provided via 2nd argument
	if (argc==3)
	{
		output = argv[2];
	}
	else output = "output/test.root";
	HistoManager* histo = new HistoManager(output);
	G4String rootname = histo->SetRootName();

	// set mandatory user action class
	//G4VUserPrimaryGeneratorAction* gen_action = new PrimaryGeneratorAction;
	//PrimaryGeneratorAction* gen_action = new PrimaryGeneratorAction;
	PrimaryGeneratorAction* gen_action = new PrimaryGeneratorAction(detector);
	runManager->SetUserAction(gen_action);

	//EventAction* event_action = new EventAction(gen_action);
	//EventAction* event_action = new EventAction(histo);
	EventAction* event_action = new EventAction(histo, gen_action);
	runManager->SetUserAction(event_action );

	// Trackingaction
	//RunAction *run_action = new RunAction();
	//runManager->SetUserAction(run_action);
	//runManager->SetUserAction(new TrackingAction(event_action));

	// Initialize G4 kernel
	runManager->Initialize();

	// Get the pointer to the UI manager and set verbosities
	//
	G4UImanager* UI = G4UImanager::GetUIpointer();
	UI->ApplyCommand("/run/verbose 0");
	UI->ApplyCommand("/event/verbose 0");
	UI->ApplyCommand("/tracking/verbose 0");
	UI->ApplyCommand("/g4test/CutsAll 30 um");
#ifdef G4VIS_USE
	G4VisManager* visManager = new G4VisExecutive;
	visManager->Initialize();
#endif

	// Get the pointer to the User Interface manager
	//
	G4UImanager * UImanager = G4UImanager::GetUIpointer();

	if (argc!=1)   // batch mode
	{
		G4String command = "/control/execute ";
		G4String fileName = argv[1];
		UImanager->ApplyCommand(command+fileName);
	}
	else           // interactive mode : define UI session
	{
#ifdef G4UI_USE
		G4UIExecutive * ui = new G4UIExecutive(argc,argv);
#ifdef G4VIS_USE
		UImanager->ApplyCommand("/control/execute macro/vis.mac");
#endif
		ui->SessionStart();
		delete ui;
#endif

#ifdef G4VIS_USE
		delete visManager;
#endif
	}
	// Job termination
	// Free the store: user actions, physics_list and detector_description are
	//                 owned and deleted by the run manager, so they should not
	//                 be deleted in the main() program !
	delete runManager;
	delete histo;

	return 0;
}
